package com.dualsportmaps.android.views;

import net.osmand.osm.MapUtils;
import net.osmand.plus.ResourceManager;
import net.osmand.plus.RotatedTileBox;
import net.osmand.plus.render.MapRenderRepositories;
import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.OsmandMapTileView;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;

public class DsmRendererLayer implements OsmandMapLayer {
	private OsmandMapTileView view;
	private final static int startZoom = 3;
	private Rect pixRect = new Rect();
	private RotatedTileBox rotatedTileBox = new RotatedTileBox(0, 0, 0, 0, 0, 0);
	private ResourceManager resourceManager;
	private Paint paintImg;
	
	private RectF destImage = new RectF();
	private boolean visible = false;
	

	@Override
	public void destroyLayer() {
		view = null;
	}

	@Override
	public boolean drawInScreenPixels() {
		return true;
	}

	@Override
	public void initLayer(OsmandMapTileView view) {
		this.view = view;
		resourceManager = view.getApplication().getResourceManager();
		paintImg = new Paint();
		paintImg.setFilterBitmap(true);
	}
	
	private void updateRotatedTileBox(){
		float ts = view.getTileSize();
		float xL = view.calcDiffTileX(pixRect.left - view.getCenterPointX(), pixRect.top - view.getCenterPointY()) + view.getXTile();
		float yT = view.calcDiffTileY(pixRect.left - view.getCenterPointX(), pixRect.top - view.getCenterPointY()) + view.getYTile();
		rotatedTileBox.set(xL, yT, ((float) pixRect.width()) / ts, ((float) pixRect.height()) / ts, view.getRotate(), view.getZoom());
	}
	
	@Override
	public void onDraw(Canvas canvas, RectF latLonBounds, boolean nightMode) {
		if (view.getZoom() >= startZoom && visible) {
			if (!view.isZooming() || view.isRotating() || resourceManager.updateRenderedMapNeeded(rotatedTileBox)){
				if(view.showPerspective()) {
					pixRect.set(0-(int)(view.getWidth()*view.matrixWidthFactor), 0-(int)(view.getHeight()*view.matrixHeightFactor), view.getWidth()+(int)(view.getWidth()*view.matrixWidthFactor), view.getHeight());
//					pixRect.set(0-view.getWidth()/3, 0-(int)(view.getHeight()*multiplier), view.getWidth()+view.getWidth()/3, view.getHeight());
				} else
					pixRect.set(0, 0, view.getWidth(), view.getHeight());				
				updateRotatedTileBox();
				if(resourceManager.updateRenderedMapNeeded(rotatedTileBox)){
					if(view.showPerspective()) {
						pixRect.set(pixRect.left-(view.getWidth() / 3), pixRect.top-(view.getHeight() / 4), 4 * pixRect.right /3, 5 * view.getHeight() / 4);
					}
					else
						pixRect.set(-view.getWidth()/3, -view.getHeight() / 4, 4 * view.getWidth() /3, 5 * view.getHeight() / 4);
					updateRotatedTileBox();
					resourceManager.updateRendererMap(rotatedTileBox);
				}
			}
			
			MapRenderRepositories renderer = resourceManager.getRenderer();
			Bitmap bmp = renderer.getBitmap();
			RotatedTileBox bmpLoc = renderer.getBitmapLocation();
			if ((bmp != null && bmpLoc != null)) {
				float mult = (float) MapUtils.getPowZoom(view.getZoom() - bmpLoc.getZoom());
				
				float tx = view.getXTile();
				float ty = view.getYTile();
				float dleftX1 = (bmpLoc.getLeftTileX() * mult - tx) ;
				float dtopY1 =  (bmpLoc.getTopTileY() * mult - ty);
				
				float cos = bmpLoc.getRotateCos();
				float sin = bmpLoc.getRotateSin();
				float x1 = MapUtils.calcDiffPixelX(sin, cos, dleftX1, dtopY1, view.getTileSize()) + view.getCenterPointX();
				float y1 = MapUtils.calcDiffPixelY(sin, cos, dleftX1, dtopY1, view.getTileSize()) + view.getCenterPointY();
				if(Math.abs(x1) > view.getWidth()/6 || Math.abs(y1) > view.getHeight()/3)
					updateRotatedTileBox();
				canvas.save();
				destImage.set(x1, y1, x1 + bmpLoc.getTileWidth() * mult * view.getTileSize(), y1 + bmpLoc.getTileHeight() * mult * view.getTileSize());
				if(view.showPerspective()) {
					view.addPerspective(canvas);
				}
				float rot = bmpLoc.getRotate();
				if(rot-view.getRotate() != 0) {
					canvas.rotate(view.getRotate()-rot, view.getCenterPointX(), view.getCenterPointY());
					updateRotatedTileBox();
				}
				if(!bmp.isRecycled()){
					canvas.drawBitmap(bmp, null, destImage, paintImg);
				}
				canvas.restore();
			}
		}
	}

	public void setVisible(boolean visible) {
		this.visible = visible;
		view.refreshMap();
	}
	
	public boolean isVisible() {
		return visible;
	}

	@Override
	public boolean onLongPressEvent(PointF point) {
		return false;
	}

	@Override
	public boolean onTouchEvent(PointF point) {
		return false;
	}
	
}

